一、OpenGL状态机和上下文
概述:
OpenGL是一个状态机,它拥有非常多的状态变量,并且每个状态变量都有默认值。
OpenGL在渲染的时候需要一个Context来记录了OpenGL渲染需要的所有信息和状态,因为OpenGL只是图形API,它没有窗口的支持。可以把它理解成一个大的结构体,它里面记录了当前绘制使用的颜色、是否有光照计算以及开启的光源等非常多我们使用OpenGL函数调用设置的状态和状态属性。
在程序中,我们设置的各种状态和默认状态会一直生效,直到我们再次修改它们。状态机并不是一个好的设计,多个绘制算法同时跑,容易被前面的状态所影响,OpenGL为了向前兼容,状态机的形式就被一直延续下来了。
上下文创建
我们一般使用glut或glfw来创建窗口,然后在这个窗口中绘制。所以上下文的意思也就是OpenGL的作用范围,在这里可以先简单的理解为就是这个窗口。也就是说,如果我们要使用OpenGL,需要先为它创建一个窗口。当然OpenGL的Context不只是这个窗口,这个窗口我们可以理解为OpenGL的default framebuffer,所以Context还包含关于这个framebuffer的一些参数设置信息,具体内容可以查看OpenGL的Context的结构体。
GPU的CS模式和上下文
如上所述,OpenGL的一组状态机对应着一个上下文。OpenGL采用了Client-Server模式,GPU相当于一台服务器,可对应多个客户端即上下文,一个客户端维护着一组状态机。大部分的OpenGL命令都是异步的,不代表真正地执行,只是客户端向服务器发送了一些命令(同时有一些API可实现同步功能)。如果两个窗口分别对应两个不同的绘制上下文,则两个窗口彼此状态独立,绘制状态不会互相影响,宏观上看绘制也是并行的。
线程私有
OpenGL的绘制命令都是作用在当前的Context上,这个Current Context是一个线程私有(thread-local)的变量,也就是说如果我们在线程中绘制,那么需要为该线程制定一个Current Context的,当多个线程参与绘制任务时,需要原线程解绑再重新绑定新的线程。多个线程不能同时指定同一个Context为Current Context,否则会导致崩溃。
OpenGL所创建的资源, 其实对程序员可见的仅仅是ID而已, 其内容依赖于这个上下文, 因此在大型程序中的一般做法是申请一条线程专门用于绘制,创建线程时,为该绘制线程申请一个绘制上下文,一直作为Current Context,不再进行切换。所有的绘制相关的操作,都在绘制线程完成。但是如果涉及复杂的OpenGL渲染时, 这样就未必足够,当有需求需多个并行的绘制任务时,则要创建多个Context,为并行的线程分别绑定不同的上下文。
共享上下文
一个是进程可以创建多个Context,它们可以分别描绘出不同的图形界面,就像一个应用程序可以打开多个窗口一样。每个OpenGL Context是相互独立的,它们都有自己的OpenGL对象集。但有时会有场景需要多个上下文使用同一份纹理资源的情况,创建Context,意味着系统资源的占用,同一份纹理重复申请会造成资源浪费,因此OpenGL上下文允许共享一部分资源。大部分OpenGL Objects是可以共享的,包括Sync Object和GLSL Objects。Container Objects和Query Objects是不能共享的。例如纹理、shader、Buffer等资源是可以共享的,但Frame Buffer Object(FBO)、Vertex Array Object(VAO)等容器对象不可共享,但可将共享的纹理和VBO绑定到各自上下文的容器对象上。上下文创建时可以指定共享上下文,具体可见示例。
OpenGL多线程绘制
实现效果:opengl开启两个线程,一个线程用于绘制,另一个线程用于加载纹理。
实现方法:opengl是单线程的,其他线程不能访问另外线程的纹理资源,但是,如果两个线程共享上下文,就可以访问彼此的纹理资源。
绘制线程:创建两个上下文
//只有主要代码
...
context = eglCreateContext(display, config, NULL, ctxAttribs);
context1 = eglCreateContext(display, config, context, ctxAttribs);
...
eglMakeCurrent(display, eglSurface, eglSurface, context);
加载纹理线程:绑定绘制线程中两个上下文中的一个
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context1);
参考:
https://blog.csdn.net/shenyi0_0/article/details/109382509
https://www.cnblogs.com/xin-lover/p/9453760.html